package com.dev.weixin.tools.utils;

import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.dev.weixin.tools.models.base.ErrorMsg;
import com.dev.weixin.tools.models.exceptions.ErrorMsgException;
import com.dev.weixin.tools.utils.policy.RequestPolicy;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * http链接
 * @author 飘渺青衣
 * @see
 */
public class WeixinHttpClient {

	private static final Logger LOG = LogManager.getLogger(WeixinHttpClient.class);
	
	private static ObjectMapper mapper = new ObjectMapper();
	
	static {
		mapper.setSerializationInclusion(Include.NON_NULL);  
	}
	
	public static <T> T request(RequestPolicy<T> policy) throws ErrorMsgException {
		HttpClientBuilder builder = HttpClientBuilder.create();
        CloseableHttpClient closeableHttpClient = builder.build();
        String t_url = getUrl(policy.getUrl(), policy.getGetParameters());
        LOG.info(t_url);
		HttpPost httpPost = new HttpPost(t_url);
		policy.request(httpPost, mapper);
		HttpResponse httpResponse = null;
		try {
			httpResponse = closeableHttpClient.execute(httpPost);
			HttpEntity entity = httpResponse.getEntity();
		    int status = httpResponse.getStatusLine().getStatusCode();
		    LOG.info("status code:" + status);
		    if (status == HttpStatus.SC_OK && entity != null) {
            	return policy.response(httpResponse, entity, mapper);
            } else {
            	ErrorMsg error = new ErrorMsg();
            	error.setErrcode(String.valueOf(status));
            	error.setErrmsg(EntityUtils.toString(entity));
            	throw new ErrorMsgException(error);
            }
		} catch (ClientProtocolException e) {
			LOG.error(e);
		} catch (IOException e) {
			LOG.error(e);
		} finally {
			HttpClientUtils.closeQuietly(httpResponse);
			HttpClientUtils.closeQuietly(closeableHttpClient);
        }
		return null;
	}
	
	private static String getUrl(String url, Map<String, String> params) {
		StringBuilder t_url = new StringBuilder();
        t_url.append(url);
        if(params != null && !params.isEmpty()) {
        	if(t_url.indexOf("?") < 0) {
        		t_url.append("?");
        	}
    		Iterator<Entry<String, String>> entries = params.entrySet().iterator();
    		Entry<String, String> entry = null;
    		while(entries.hasNext()) {
    			entry = entries.next();
    			t_url.append(entry.getKey()).append("=").append(entry.getValue());
    			if(entries.hasNext()) {
    				t_url.append("&");
    			}
    		}
        }
        return t_url.toString();
	}
	
}
